/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package clientprogram;

import Command.CommandStatement;
import Command.Constant_Command;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import remoteclient.ClientInitiator;

/**
 *
 * @author ASUS
 */
public class SocketCommunication extends Thread {

    private Socket socket;
    private ObjectInputStream ois;
    private ObjectOutputStream oos;
    private boolean isWorking = true;
    private ClientInitiator TeamViewThread = null;
    //Single alone
    private static SocketCommunication instance = null;

    public static SocketCommunication Instance() {
        if (instance == null) {
            instance = new SocketCommunication();
        }
        return instance;
    }

    public SocketCommunication() {

    }

    public void Init(Socket _socket) {
        this.socket = _socket;

        try {
            oos = new ObjectOutputStream(socket.getOutputStream());
            oos.flush();
            ois = new ObjectInputStream(socket.getInputStream());
            start();
        } catch (Exception e) {
            Logger.getLogger(e.getMessage());
        }
    }

    public void SendCommand(CommandStatement statement) {
        try {
            oos.writeObject(statement);
        } catch (Exception e) {
            Logger.getLogger(e.getMessage());
        }
    }

    public CommandStatement GetResult() {
        try {
            CommandStatement result = (CommandStatement) ois.readObject();
            return result;
        } catch (Exception e) {
            Logger.getLogger(e.getMessage());
            return null;
        }
    }

    public void Shutdown() throws IOException {
        Runtime runtime = Runtime.getRuntime();
        Process proc = runtime.exec("shutdown -s -t 0");
        System.exit(0);
    }

    public void Restart() throws IOException {
        Runtime runtime = Runtime.getRuntime();
        Process proc = runtime.exec("shutdown -r -t 0");
        System.exit(0);
    }

    @Override
    public void run() {

        while (isWorking) {
            try {
                System.out.println("Waiting for object...");
                CommandStatement comm = (CommandStatement) ois.readObject();
                System.out.println("Server send: " + comm.getId() + comm.getSt1() + comm.getSt2());
                switch (comm.getId()) {
                    case Constant_Command.TURN_ON_SERVICE:
                        User.Instance().username = comm.getSt1();
                        User.Instance().minRemain = Integer.parseInt(comm.getSt2());
                        LockScreen.Instance().Close();
                        break;
                    case Constant_Command.TURN_OFF_SERVICE:
                        if (!LockScreen.Instance().working){
                            SendCommand(new CommandStatement(Constant_Command.TURN_OFF_SERVICE, User.Instance().startTime, String.valueOf(User.Instance().totalTimeUsed)));
                            LockScreen.Instance().Open();
                        }
                        break;
                    case Constant_Command.SHUT_DOWN:
                        Shutdown();
                        break;
                    case Constant_Command.RESTART:
                        Restart();
                        break;
                    case Constant_Command.TEAMVIEW:
                        if (TeamViewThread != null && TeamViewThread.isAlive()){
                           TeamViewThread.interrupt();
                           TeamViewThread.suspend();
                        }
                        TeamViewThread = new ClientInitiator();
                        break;
                    case Constant_Command.TURNOFF_TEAMVIEW:
                        if (TeamViewThread != null && TeamViewThread.IsWorking){
                            TeamViewThread.IsWorking = false;
                        }
                        break;
                    case Constant_Command.PURE_MESSAGE:
                        if (LockScreen.Instance().working) {
                            new PureMessageDialog(LockScreen.Instance().frame, true, comm.getSt1()).setVisible(true);
                        } else {
                            new PureMessageDialog(null, true, comm.getSt1()).setVisible(true);
                        }
                        break;
                    case Constant_Command.UPDATEMINREMAIN:
                        User.Instance().minRemain = Integer.parseInt(comm.getSt1());
                        break;
                    case Constant_Command.UPDATEPRICEPERHOUR:
                        User.Instance().pricePerHour = Integer.parseInt(comm.getSt1());
                        break;
                }
            } catch (IOException ex) {
                Logger.getLogger(SocketCommunication.class.getName()).log(Level.SEVERE, null, ex);
            } catch (ClassNotFoundException ex) {
                Logger.getLogger(SocketCommunication.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

}
